﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
using System.Text.RegularExpressions;
using XRMSolutions.NToNImportExport.Control.Crm;
using System.ServiceModel;

namespace XRMSolutions.NToNImportExport.Control
{
    internal class SilverlightHelper
    {
        internal static IOrganizationService GetSoapService()
        {
            Uri serviceUrl = new Uri(GetServerUrl() + "/XRMServices/2011/Organization.svc/web");  

            BasicHttpBinding binding = new BasicHttpBinding(Uri.UriSchemeHttps == serviceUrl.Scheme
                ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.TransportCredentialOnly);
            binding.MaxReceivedMessageSize = int.MaxValue;
            binding.MaxBufferSize = int.MaxValue;
            binding.SendTimeout = TimeSpan.FromMinutes(2);

            return new OrganizationServiceClient(binding, new EndpointAddress(serviceUrl));
        }

        private static string GetServerUrl()
        {
            var context = GetContext();
            var isOutlookClient = (bool)context.Invoke("isOutlookClient");
            var isOutlookOnline = (bool)context.Invoke("isOutlookOnline");

            var documentUri = HtmlPage.Document.DocumentUri;

            var localServerUrl = string.Format("{0}://{1}:{2}", documentUri.Scheme, documentUri.Host, documentUri.Port);
            if (isOutlookClient && !isOutlookOnline)
            {
                return localServerUrl;
            }

            var baseServerUrl = (string)context.Invoke("getServerUrl");
            var serverUrl = Regex.Replace(baseServerUrl, @"^(http|https):\/\/([_a-zA-Z0-9\-\.]+)(:([0-9]{1,5}))?", localServerUrl);
            return Regex.Replace(serverUrl, @"\/$", string.Empty);
        }

        private static ScriptObject GetContext()
        {
            var xrmProperty = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
            if (null == xrmProperty)
            {
                //It may be that the global context should be used
                try
                {
                    var globalContext = (ScriptObject)HtmlPage.Window.Invoke("GetGlobalContext");

                    return globalContext;
                }
                catch (InvalidOperationException)
                {
                    throw new InvalidOperationException("Property \"Xrm\" is null and the Global Context is not available.");
                }
            }

            var pageProperty = (ScriptObject)xrmProperty.GetProperty("Page");
            if (null == pageProperty)
            {
                throw new InvalidOperationException("Property \"Xrm.Page\" is null");
            }

            var contextProperty = (ScriptObject)pageProperty.GetProperty("context");
            if (null == contextProperty)
            {
                throw new InvalidOperationException("Property \"Xrm.Page.context\" is null");
            }

            return contextProperty;
        }
    }

    internal class Marker
    {
        internal Marker()
        {
            FirstEntityId = Guid.Empty;
            SecondEntityId = Guid.Empty;
        }

        internal IOrganizationService Service
        {
            get;
            set;
        }

        internal string FirstEntityLogicalName
        {
            get;
            set;
        }

        internal string FirstEntityLookupFieldValue
        {
            get;
            set;
        }

        internal Guid FirstEntityId
        {
            get;
            set;
        }

        internal string SecondEntityLogicalName
        {
            get;
            set;
        }
        
        internal Guid SecondEntityId
        {
            get;
            set;
        }

        internal string SecondEntityLookupFieldName
        {
            get;
            set;
        }

        internal string SecondEntityLookupFieldValue
        {
            get;
            set;
        }

        internal string RelationShipName
        {
            get;
            set;
        }

        internal int LineNumber
        {
            get;
            set;
        }
    }
}
